#ifndef __DEBUG__
// For printing purposes
#define __DEBUG__ 0
#endif

#include <iostream>
#include <cstdint>

#include "../VAR.hpp"
#include "../TERM.hpp"
#include "../EXPRESSION.hpp"
#include "../ADD.hpp"
#include "../SUB.hpp"
#include "../MIN.hpp"
#include "../MAX.hpp"
#include "../CEIL.hpp"
#include "../FLOOR.hpp"

using namespace std;

// Global variables for printing and debugging purposes
int expr_depth = -1;
int bin_expr_depth = -1;

void test4() {
  constexpr Variable<1> v1;
  constexpr VariableTerm<1> t1(v1);
  constexpr Variable<2> v2;
  constexpr VariableTerm<2> t2(v2);
  constexpr Variable<3> v3;
  constexpr VariableTerm<3> t3(v3);

  auto expr01 = CEIL(-5, 4);
  if (__DEBUG__) cout << endl << "\tEXPR01 evals to " << endl <<  expr01 << endl;
  auto expr02 = CEIL(-2*t1-5, 16);
  if (__DEBUG__) cout << endl << "\tEXPR02 evals to " << endl <<  expr02 << endl;
  auto expr03 = CEIL(-2*t1+4+3*t2, 32);
  if (__DEBUG__) cout << endl << "\tEXPR03 evals to " << endl <<  expr03 << endl;
  auto expr04 = CEIL(-2*t1+4+3*t2-(4*(-3))*t3-5, 64);
  if (__DEBUG__) cout << endl << "\tEXPR04 evals to " << endl <<  expr04 << endl;
  
  auto expr11 = FLOOR(-5, 4);
  if (__DEBUG__) cout << endl << "\tEXPR11 evals to " << endl <<  expr11 << endl;
  auto expr12 = FLOOR(-2*t1-5, 16);
  if (__DEBUG__) cout << endl << "\tEXPR12 evals to " << endl <<  expr12 << endl;
  auto expr13 = FLOOR(-2*t1+4+3*t2, 32);
  if (__DEBUG__) cout << endl << "\tEXPR13 evals to " << endl <<  expr13 << endl;
  auto expr14 = FLOOR(-2*t1+4+3*t2-(4*(-3))*t3-5, 64);
  if (__DEBUG__) cout << endl << "\tEXPR14 evals to " << endl <<  expr14 << endl;

  auto expr21 = MIN(-5, 4);
  if (__DEBUG__) cout << endl << "\tEXPR21 evals to " << endl <<  expr21 << endl;
  auto expr22 = MIN(-2*t1-5, 16);
  if (__DEBUG__) cout << endl << "\tEXPR22 evals to " << endl <<  expr22 << endl;
  auto expr23 = MIN(-2*t1+4+3*t2, 32);
  if (__DEBUG__) cout << endl << "\tEXPR23 evals to " << endl <<  expr23 << endl;
  auto expr24 = MIN(-2*t1+4+3*t2-(4*(-3))*t3-5, 64);
  if (__DEBUG__) cout << endl << "\tEXPR24 evals to " << endl <<  expr24 << endl;

  auto expr25 = MIN(MIN(-5, 4), FLOOR(-2*t1+4+3*t2, 32));
  if (__DEBUG__) cout << endl << "\tEXPR25 evals to " << endl <<  expr25 << endl;
  auto expr26 = MIN(expr24, expr11);
  if (__DEBUG__) cout << endl << "\tEXPR26 evals to " << endl <<  expr26 << endl;
  auto expr27 = MIN(-2*t1+4+3*t2, expr21);
  if (__DEBUG__) cout << endl << "\tEXPR27 evals to " << endl <<  expr27 << endl;
  auto expr28 = MIN(expr22, -2*t1+4+3*t2-(4*(-3))*t3-5);
  if (__DEBUG__) cout << endl << "\tEXPR28 evals to " << endl <<  expr28 << endl;
  auto expr29 = MIN(expr23, expr24);
  if (__DEBUG__) cout << endl << "\tEXPR29 evals to " << endl <<  expr29 << endl;

}

int main (void) {
  test4();
}
